package com.ncmmall.api.apis.mall;


import com.ncmmall.api.apis.service.Result;
import com.ncmmall.api.params.DataDTO;
import com.ncmmall.api.security.Securitys;
import com.ncmmall.application.business.coupon.CouponApplication;
import com.ncmmall.domain.business.advertis.Advertis;
import com.ncmmall.domain.business.advertis.QAdvertis;
import com.ncmmall.domain.business.goods.Goods;
import com.ncmmall.domain.business.marketing.coupon.Coupon;
import com.ncmmall.domain.business.marketing.coupon.CouponChannel;
import com.ncmmall.domain.business.marketing.coupon.CouponGoods;
import com.ncmmall.domain.business.marketing.coupon.CouponMemberDraw;
import com.ncmmall.domain.business.marketing.coupon.QCoupon;
import com.ncmmall.domain.business.marketing.coupon.QCouponChannel;
import com.ncmmall.domain.business.marketing.coupon.QCouponGoods;
import com.ncmmall.domain.business.marketing.coupon.QCouponMemberDraw;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.querychannel.QueryPage;
import com.ncmmall.querychannel.QueryPageRequest;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 优惠券中心
 *
 * @author likaikai
 * @date 2020-09-24 11:45:13
 */
@RestController
@RequestMapping(value = "/coupon")
@Slf4j
public class CouponApi {

    @Autowired
    private CouponApplication couponApplication;

    @Autowired
    private QueryChannelService queryChannelService;

    @Value("${store.domain}")
    private String storeDomain;

    /**
     * 领劵中心
     */
    @GetMapping(value = "/center")
    public Result couponCenter() {

        Result result = new Result();
        try {
            List<Map<String, Object>> channels = queryChannelService.selectAllMap("select * from mall_goods_channel where parent is null and status = 1 and deleteStatus = 0", ImmutableMap.of());
            List<Advertis> advertises = queryChannelService.findAll(QAdvertis.advertis.position.eq(5).and(QAdvertis.advertis.status.eq(2)), Advertis.class);
            for (Advertis advertise : advertises) {
                advertise.setImage(storeDomain + "/uploads/" + advertise.getImage());
            }
            return result.ok().inject(ImmutableMap.of("channels", channels, "banners", advertises));
        } catch (IllegalArgumentException e) {
            return result.fail().setMsg(e.getMessage());
        } catch (Exception e) {
            log.error("[领劵中心获取数据异常]", e);
            return result.fail().setMsg("网络连接失败");
        }
    }

    /**
     * 我领取的优惠券数量
     */
    @GetMapping(value = "/drawInfo")
    public Result drawInfo(HttpServletRequest request) {
        Result result = new Result();
        try {

            WebUser member = Securitys.user(request);

            int noUseCouponCount = queryChannelService.selectCount("select count(1) from mall_coupon_member_draw where member_id = :mid and status = 1 ", ImmutableMap.of("mid", member.getId()));
            int useCouponCount = queryChannelService.selectCount("select count(1) from mall_coupon_member_draw where member_id = :mid and status = 2 ", ImmutableMap.of("mid", member.getId()));
            int dueCouponCount = queryChannelService.selectCount("select count(1) from mall_coupon_member_draw where member_id = :mid and status = 3 ", ImmutableMap.of("mid", member.getId()));

            return result.ok().inject(ImmutableMap.of("noUseCouponCount", noUseCouponCount, "useCouponCount", useCouponCount, "dueCouponCount", dueCouponCount));

        } catch (IllegalArgumentException e) {
            return result.fail().setMsg(e.getMessage());
        } catch (Exception e) {

            log.error("[领劵中心获取数据异常]", e);
            return result.fail().setMsg("网络连接失败");
        }

    }

    /**
     * 我领取的优惠券
     */
    @GetMapping(value = "/drawList")
    public Result drawList(HttpServletRequest request, @RequestParam("status") int status, @RequestParam(defaultValue = "1") int pageNo, @RequestParam(defaultValue = "20") int pageSize) {

        Result result = new Result();
        try {

            QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageNo).setPageSize(pageSize);
            Map<String, Object> map = new HashMap<>();

            WebUser member = Securitys.user(request);

            String hql = "select c.coupon from CouponMemberDraw c where c.member.id = :id and c.status = :status ";

            map.put("id", member.getId());
            map.put("status", status);

            hql += " order by c.drawTime desc ";
            QueryPage<Coupon> page = queryChannelService.findPage(hql, pageRequest.setParams(map), Coupon.class);

            for (Coupon coupon : page.getResult()) {
                if (null != coupon.getComplimentaryGoods()) {
                    coupon.getComplimentaryGoods().setDefaultImage(storeDomain + "/uploads/" + coupon.getComplimentaryGoods().getDefaultImage());
                }
                QCouponMemberDraw draw = QCouponMemberDraw.couponMemberDraw;
                CouponMemberDraw memberDraw = queryChannelService.findOne(draw.member.eq(member).and(draw.coupon.eq(coupon)), CouponMemberDraw.class);
                if (null != memberDraw) {
                    coupon.setGetStatus(memberDraw.getStatus());
                    coupon.setExpirationTime(memberDraw.getExpirationTime());
                    coupon.setDrawTime(memberDraw.getDrawTime());
                }
            }
            return result.ok().inject(page);
        } catch (Exception e) {
            log.error("[优惠券列表获取数据异常]", e);
            return result.fail().setMsg("网络连接失败");
        }
    }


    /**
     * 领劵中心优惠券列表
     */
    @GetMapping(value = "/list")
    public Result list(HttpServletRequest request, @RequestParam("id") long id, @RequestParam(defaultValue = "1") int pageNo, @RequestParam(defaultValue = "20") int pageSize) {

        Result result = new Result();
        try {

            QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageNo).setPageSize(pageSize);
            Map<String, Object> map = new HashMap<>();

            String hql = "select c from Coupon c where c.publishStatus = 2 and c.status = 2  ";

            if (id > 0) {
                hql += " and c.id in (select cc.coupon.id from CouponChannel cc where cc.channel.id = :cid ) ";
                map.put("cid", id);
            } else {
                hql += " and c.choiceStatus = 2 ";
            }

            hql += " order by c.createTime desc ";


            QueryPage<Coupon> page = queryChannelService.findPage(hql, pageRequest.setParams(map), Coupon.class);

            for (Coupon coupon : page.getResult()) {
                if (null != coupon.getComplimentaryGoods()) {
                    coupon.getComplimentaryGoods().setDefaultImage(storeDomain + "/uploads/" + coupon.getComplimentaryGoods().getDefaultImage());
                }
                if (Securitys.isLogin(request)) {
                    WebUser member = Securitys.user(request);
                    QCouponMemberDraw draw = QCouponMemberDraw.couponMemberDraw;
                    CouponMemberDraw memberDraw = queryChannelService.findOne(draw.member.eq(member).and(draw.coupon.eq(coupon)), CouponMemberDraw.class);
                    if (null != memberDraw) {
                        coupon.setGetStatus(memberDraw.getStatus());
                        coupon.setExpirationTime(memberDraw.getExpirationTime());
                        coupon.setDrawTime(memberDraw.getDrawTime());
                    }
                }
            }

            return result.ok().inject(page);

        } catch (Exception e) {
            log.error("[优惠券列表获取数据异常]", e);
            return result.fail().setMsg("网络连接失败");
        }

    }

    /**
     * 查看优惠券的适用商品列表
     */
    @GetMapping(value = "/scopeGoodses")
    public Result scopeGoodses(@RequestParam("id") long id, @RequestParam(defaultValue = "1") int pageNo, @RequestParam(defaultValue = "20") int pageSize) {

        Result result = new Result();
        try {

            Coupon coupon = queryChannelService.findOne(QCoupon.coupon.id.eq(id), Coupon.class);

            Map<String, Object> map = new HashMap<>();
            String hql = "select c from Goods c where c.merchant.id = :id and c.status = 3";
            map.put("id", coupon.getMerchant().getId());

            //指定品类可用
            List<CouponChannel> couponChannels = queryChannelService.findAll(QCouponChannel.couponChannel.coupon.id.eq(id), CouponChannel.class);
            if (CollectionUtils.isNotEmpty(couponChannels)) {
                List<Long> channelIds = couponChannels.stream().map(c -> c.getChannel().getId()).collect(Collectors.toList());
                hql += " and c.goodsChannel.parent.parent.id in (:channelIds)";
                map.put("channelIds", channelIds);
            }

            //指定的商品可用
            if (coupon.getScopeType() == 2) {
                List<CouponGoods> couponGoodsList = queryChannelService.findAll(QCouponGoods.couponGoods.coupon.id.eq(id), CouponGoods.class);
                if (CollectionUtils.isNotEmpty(couponGoodsList)) {
                    List<Long> goodsIds = couponGoodsList.stream().map(c -> c.getGoods().getId()).collect(Collectors.toList());
                    hql += " and c.id in (:goodsIds)";
                    map.put("goodsIds", goodsIds);
                }
            }
            hql += " order by c.createTime desc ";

            QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageNo).setPageSize(pageSize);
            QueryPage<Goods> page = queryChannelService.findPage(hql, pageRequest.setParams(map), Goods.class);

            for (Goods goods : page.getResult()) {
                goods.setDefaultImage(storeDomain + "/uploads/" + goods.getDefaultImage());
            }
            return result.ok().inject(page);

        } catch (Exception e) {
            log.error("[查看优惠券适用商品获取数据异常]", e);
            return result.fail().setMsg("网络连接失败");
        }
    }


    /**
     * 领取优惠券
     */
    @PostMapping("/draw")
    public Result draw(HttpServletRequest request, @RequestBody DataDTO params) {

        Result result = new Result();
        try {
            WebUser member = Securitys.user(request);
            Coupon coupon = queryChannelService.findOne(QCoupon.coupon.id.eq(params.getId()).and(QCoupon.coupon.publishStatus.eq(2)), Coupon.class);
            if (null == coupon) {
                return result.fail().setMsg("优惠券不存在");
            }

            int count = queryChannelService.selectCount("select count(*) from mall_coupon_member_draw where coupon_id = :cid and member_id = :mid",
                    ImmutableMap.of("cid", coupon.getId(), "mid", member.getId()));
            if (count > 0) {
                return result.fail().setMsg("不能重复领取");
            }
            CouponMemberDraw memberDraw = couponApplication.draw(member, coupon);
            return result.ok().inject(memberDraw);
        } catch (IllegalArgumentException e) {
            return result.fail().setMsg(e.getMessage());
        } catch (Exception e) {
            log.error("[优惠券领取异常]", e);
            return result.fail().setMsg("网络请求异常");
        }
    }

}
